package uk.ac.glasgow.oose2.gcf.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * Provides basic functionality for a Reverse Polish Notation Calculator equipped with 
 * 10 accumulators.
 * @author tws
 *
 * @param <S> the type of values the RPN calculator operates on.
 */
public abstract class RPNCalculator<S> {

	/** The storage for the calculator */
	final protected List<Accumulator> accumulators = new ArrayList<Accumulator>();
	
	/** The stack for performing RPN operations */
	final protected Stack<S> stack = new Stack<S>();

	/**
	 * Constructs a new RPNCalculator
	 */
	public RPNCalculator(){
		clear();
	}
	
	/**
	 * clear the calculator by purging all elements from the stack and reseting all values of accumulators
	 * operations are NOT reset.
	 */
	public void clear() {
		
		stack.clear();
		accumulators.clear();
				
		for (int i = 0; i < 10; i++) 
			accumulators.add(new Accumulator());
	}
	
	//data operations
	
	/**
	 * Pops and returns the top element of the calculator's stack.
	 * @return the value on the top of the stack
	 */
	public S result() throws CalculatorException{
		if (stack.isEmpty()) throw new CalculatorException("result","empty stack");
		else return stack.pop();
	}
	
	/**
	 * returns the top element of the calculator's stack.
	 * @return the value on the top of the stack
	 * @throws CalculatorException
	 */
	public S top() throws CalculatorException {
		if (stack.isEmpty()) throw new CalculatorException("result","empty stack");
		else return stack.peek();
	}
	/**
	 * Pushes a value onto the calculator's stack
	 * @param value the value to push
	 */
	public void enter(S value) {
		stack.push(value);
	}
}
